﻿using Basic.FlowDAL;
using Basic.FlowModel.DB;
using Basic.FlowModel.EventTemplate;
using Basic.FlowRemoteModel;
using Basic.FlowRemoteModel.EventTemplate.Model;
using WeDonekRpc.CacheClient.Interface;
using WeDonekRpc.Helper;
using WeDonekRpc.Model;

namespace Basic.FlowCollect.lmpl
{
    internal class EventTemplateCollect : IEventTemplateCollect
    {
        private readonly IFlowEventTemplateDAL _BasicDAL;
        private readonly ILocalCacheController _LocalCache;
        public EventTemplateCollect ( IFlowEventTemplateDAL basicDAL, ILocalCacheController localCache )
        {
            this._LocalCache = localCache;
            this._BasicDAL = basicDAL;
        }
        public DBFlowEventTemplate Get ( long id )
        {
            return this._BasicDAL.Get(id);
        }
        public Result Get<Result> ( long id ) where Result : class, new()
        {
            return this._BasicDAL.Get<Result>(id);
        }
        public void Delete ( DBFlowEventTemplate source )
        {
            if ( source.Status != FlowInterStatus.起草 )
            {
                throw new ErrorException("flow.inter.status.error");
            }
            this._BasicDAL.Delete(source.Id);
            this._Remove(source.Id);
        }
        public long Add ( EventTemplateAdd add )
        {
            if ( this._BasicDAL.IsExists(c => c.InterName == add.InterName) )
            {
                throw new ErrorException("flow.inter.name.repeat");
            }
            return this._BasicDAL.Add(add);
        }
        public bool Set ( DBFlowEventTemplate source, EventTemplateSet set )
        {
            if ( source.Status == FlowInterStatus.启用 )
            {
                throw new ErrorException("flow.inter.status.error");
            }
            if ( source.InterName != set.InterName && this._BasicDAL.IsExists(c => c.InterName == set.InterName) )
            {
                throw new ErrorException("flow.inter.name.repeat");
            }
            if ( this._BasicDAL.Update(source, set) )
            {
                this._Remove(source.Id);
                return true;
            }
            return false;
        }
        public Result[] Query<Result> ( InterQueryParam query, IBasicPage paging, out int count ) where Result : class
        {
            return this._BasicDAL.Query<Result>(query, paging, out count);
        }

        public Result[] Gets<Result> () where Result : class, new()
        {
            return this._BasicDAL.Gets<Result>(a => a.Status == FlowInterStatus.启用);
        }

        public Dictionary<long, string> GetNames ( long[] ids )
        {
            return this._BasicDAL.Gets(ids, a => new
            {
                a.Id,
                a.InterName
            }).ToDictionary(a => a.Id, a => a.InterName);
        }
        private void _Remove ( long evId )
        {
            string key = "EventDto_" + evId;
            _ = this._LocalCache.Remove(key);
        }
        public EventDto GetEvent ( long evId )
        {
            string key = "EventDto_" + evId;
            if ( this._LocalCache.TryGet(key, out EventDto dto) )
            {
                return dto;
            }
            dto = this._BasicDAL.Get<EventDto>(evId);
            _ = this._LocalCache.Set(key, dto, DateTime.Now.AddHours(12));
            return dto;
        }

        public bool Disable ( DBFlowEventTemplate source )
        {
            if ( source.Status == FlowInterStatus.停用 )
            {
                return false;
            }
            this._BasicDAL.SetStatus(source, FlowInterStatus.停用);
            this._Remove(source.Id);
            return true;
        }

        public bool Enable ( DBFlowEventTemplate source )
        {
            if ( source.Status == FlowInterStatus.启用 )
            {
                return false;
            }
            this._BasicDAL.SetStatus(source, FlowInterStatus.启用);
            this._Remove(source.Id);
            return true;
        }
    }
}
